import logging
import time

import serial
from PyQt5.QtCore import pyqtSignal, QThread

import errorhandle


def parseParity(parityBit):
    if parityBit == 'NONE':
        parityBit = serial.PARITY_NONE
    elif parityBit == 'ODD':
        parityBit = serial.PARITY_ODD
    elif parityBit == 'EVEN':
        parityBit = serial.PARITY_EVEN
    elif parityBit == 'MARK':
        parityBit = serial.PARITY_MARK
    else:
        parityBit = serial.PARITY_SPACE
    return parityBit


class SerialDataThread(QThread):
    trigger = pyqtSignal(list)

    def __int__(self, parent=None, config={}):
        super(SerialDataThread, self).__init__()
        self.setObjectName("SerialDataThread")

    def init(self, config):
        self.config = config
        self.is_running = False
        self.is_ready = False
        self.conn = ''

    def connect(self):
        try:
            self.conn = serial.Serial(self.config["SERIAL_NUM"], self.config["BAUD_RATE"], timeout=0.2)
            self.conn.bytesize = self.config["DATA_BIT"]
            self.conn.parity = parseParity(self.config["PARITY"])
            self.conn.stopbits = self.config["STOP_BIT"]
            self.is_ready = True
            return 0
        except BaseException as e:
            logging.error("Serial Connect exception: " + str(e))
            return errorhandle.SERIAL_CONNECT_EXCEPTION, e

    def disconnect(self):
        try:
            if self.conn.isOpen():
                self.conn.close()
                return 0
        except Exception as e:
            logging.error("Serial disconnect exception: " + str(e))
            return errorhandle.SERIAL_DISCONNECT_FAILURE
        return 0

    def send(self, cmd):
        logging.info("Send cmd: ", cmd)
        try:
            hex_cmd = bytes.fromhex(cmd)
            self.conn.write(hex_cmd)
            return 0
        except Exception as e:
            logging.error("ERROR WHILE SENDING CMD TO SERIAL.")
            return e

    def recv(self, size):
        maxTry = 20
        while maxTry > 0:
            package = self.conn.read(size)
            if len(package) > 0:
                return package
            else:
                maxTry -= 1
        return errorhandle.SERIAL_NO_RETURN_DATA

    def run(self):
        if self.is_ready:
            while self.is_running:
                data = [x for x in range(0, 10)]
                self.trigger.emit(data)
                time.sleep(self.config['TIMER_INTERVAL'])